import React from "react";
import { Button, Tree } from "antd";
import { RightOutlined, LeftOutlined } from "@ant-design/icons";
import { cloneDeep } from "lodash";
import "./index.less";
export interface TreeTransferProps {
  onRight: (arr: any[]) => any;
  dataSource: any[];
  defaultValue?: any[];
}

export interface TreeTransferState {}

class TreeTransfer extends React.Component<
  TreeTransferProps,
  TreeTransferState
> {
  // state = { :  }

  private treeLeftData: any[] = []; //树型结构完整菜单
  private dataList: any[] = []; //平面结构完整菜单
  private leftAllCheck: string[] = []; //左侧当前选中的元素及其祖先元素
  private leftCheck: string[] = []; //左侧当前选中的元素
  private rightdataList: any[] = []; //右侧平面结构菜单
  private rightAllCheck: string[] = []; //右侧当前选中的元素及其祖先元素
  private rightCheck: string[] = []; //右侧当前选中的元素
  private treeRightData: any[] = []; //右侧树型结构菜单
  render() {
    return (
      <>
        <div className="transfer">
          <div className="transfer-list" style={{ width: 300, height: 300 }}>
            <div className="transfer-list-header">
              <span className="transfer-list-header-title">菜单列表</span>
            </div>
            <div className="transfer-list-body">
              <div className="transfer-list-content">
                <Tree
                  checkable
                  defaultExpandAll={true}
                  treeData={this.treeLeftData}
                  onCheck={(checkedKeys: any, info: any) => {
                    this.onLeftCheck(checkedKeys, info);
                  }}
                ></Tree>
              </div>
            </div>
          </div>
          <div className="transfer-operation">
            <Button
              icon={<RightOutlined />}
              onClick={() => {
                this.setRight();
              }}
            ></Button>
            <Button
              icon={<LeftOutlined />}
              onClick={() => {
                this.setLeft();
              }}
            ></Button>
          </div>
          <div className="transfer-list" style={{ width: 300, height: 300 }}>
            <div className="transfer-list-header">
              <span className="transfer-list-header-title">授权列表</span>
            </div>
            <div className="transfer-list-body">
              <div className="transfer-list-content">
                <Tree
                  checkable
                  defaultExpandAll={true}
                  treeData={this.treeRightData}
                  onCheck={(checkedKeys: any, info: any) => {
                    this.onRightCheck(checkedKeys, info);
                  }}
                ></Tree>
              </div>
            </div>
          </div>
        </div>
      </>
    );
  }

  //钩子函数
  componentWillMount() {
    // this.getMenuList();
    this.init();
  }
  shouldComponentUpdate(newProps, newState) {
    if (newProps.defaultValue) {
      this.rightdataList = this.getKeyInList(newProps.defaultValue);
      this.treeRightData = this.listToTree(this.rightdataList);
    }
    return true;
  }
  init() {
    this.dataList = this.props.dataSource; //菜单平面数据
    this.treeLeftData = this.listToTree(this.props.dataSource); //菜单树状数据
    if (this.props.defaultValue && this.props.defaultValue.length > 0) {
      this.rightdataList = this.getKeyInList(this.props.defaultValue);
      this.treeRightData = this.listToTree(this.rightdataList);
    }
    this.forceUpdate();
  }

  /**操作 */
  //获取右侧列表的所有key
  getRiglistKey() {
    let arr: any = [];
    this.rightdataList.map((item: any) => {
      arr.push(item.key);
      return item;
    });
    return arr;
  }
  getKeyInList(arr: any) {
    let array: any[] = [];
    let { dataList } = this;
    arr.map((item) => {
      for (let i = 0; i < dataList.length; i++) {
        if (dataList[i].key === item) {
          array.push(dataList[i]);
        }
      }
      return item;
    });
    return array;
  }
  //向右授权传递数据
  setRight() {
    let { leftAllCheck, dataList, leftCheck } = this;
    let riglistKey = this.getRiglistKey();
    let result = Array.from(new Set(leftAllCheck.concat(riglistKey)));
    let arr: any = [];
    dataList = dataList.map((item) => {
      let bianji = false;
      for (let i = 0; i < result.length; i++) {
        if (item.key === result[i]) {
          let citem = cloneDeep(item);
          citem.disabled = false;
          arr.push(citem);
        }
      }
      for (let i = 0; i < leftCheck.length; i++) {
        if (item.key === leftCheck[i]) {
          bianji = true;
        }
      }
      item.disabled = bianji;
      return item;
    });
    console.log(dataList);
    //生成右侧树结构
    this.rightdataList = arr;
    this.props.onRight(this.getRiglistKey());
    this.treeRightData = this.listToTree(arr);
    this.forceUpdate();
  }
  //向左传递数据并解除不可选状态
  setLeft() {
    let { rightAllCheck, rightCheck } = this;
    this.dataList = this.dataList.map((item) => {
      let biaoji = false;
      for (let i = 0; i < rightAllCheck.length; i++) {
        if (item.key === rightAllCheck[i]) {
          biaoji = true;
        }
      }
      if (biaoji) {
        item.disabled = false; //取消不可行
      }
      //其他不变
      return item;
    });
    let arr: any[] = [];
    //找出右侧没有被选中的
    this.rightdataList.map((item) => {
      let sele = false;
      for (let i = 0; i < rightCheck.length; i++) {
        if (item.key === rightCheck[i]) {
          sele = true;
        }
      }
      if (sele === false) {
        arr.push(item);
      }
      return item;
    });

    this.rightdataList = arr;
    this.props.onRight(this.getRiglistKey());
    this.treeRightData = this.listToTree(arr);
    this.forceUpdate();
  }
  onLeftCheck = (checkedKeys: string[], info: any) => {
    this.leftCheck = checkedKeys;
    this.leftAllCheck = checkedKeys.concat(info.halfCheckedKeys);
    // this.forceUpdate();
  };
  onRightCheck = (checkedKeys: string[], info: any) => {
    this.rightCheck = checkedKeys;
    this.rightAllCheck = checkedKeys.concat(info.halfCheckedKeys);
    // this.forceUpdate();
  };
  /**重新组成树结构。 */
  listToTree = (list: any) => {
    if (!Array.isArray(list) || list.length === 0) return list;
    let map: any = {},
      roots: any = [];
    for (let i = 0; i < list.length; i++) {
      map[list[i].key] = i;
      list[i].children = [];
    }
    for (let i = 0; i < list.length; i++) {
      let node = list[i];
      if (node.parentkey === null) {
        roots.push(node);
      } else {
        list[map[node.parentkey]].children.push(node);
      }
    }
    return roots;
  };
}

export default TreeTransfer;
